package com.spinach.game.hander;

import com.alibaba.fastjson2.JSONObject;
import com.spinach.game.config.DouDiZhuConfig;
import com.spinach.game.core.GameMessage;
import com.spinach.game.core.Room;
import com.spinach.game.core.UserInfo;
import com.spinach.game.enums.RoomStatus;
import com.spinach.game.enums.ServerEventCode;
import com.spinach.game.events.ServerEvent;
import com.spinach.game.events.impl.BaseServerEvent;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 自定义处理类
 * TextWebSocketFrame: websocket数据是帧的形式处理
 */
@Slf4j
@Component
@ChannelHandler.Sharable //设置通道共享
public class WebsocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> implements InitializingBean {

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private DouDiZhuConfig douDiZhuConfig;

    @Autowired
    private BaseServerEvent baseServerEvent;

    private final Map<ServerEventCode, ServerEvent> serverEventMap = new HashMap<>();

    /**
     * 通道就绪事件
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("有新的连接.");
    }

    /**
     * 通道未就绪--channel下线
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {

    }

    /**
     * 读就绪事件
     *
     * @param ctx
     * @param textWebSocketFrame
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame textWebSocketFrame) throws Exception {
        Channel ch = ctx.channel();
        String jsonMsg = textWebSocketFrame.text();
        GameMessage message = JSONObject.parseObject(jsonMsg, GameMessage.class);

        Long userId = message.getUserId();
        UserInfo user = douDiZhuConfig.getUser(userId);
        if (Objects.isNull(user)) {
            //发送房间不存在的消息
            log.info("用户不存在，userId:{}", userId);
            baseServerEvent.sendUserDoesNotExist(ch, userId);
            return;
        }

        Long roomId = message.getRoomId();
        Room room = douDiZhuConfig.getRoom(roomId);
        if (Objects.isNull(room)) {
            //发送房间不存在的消息
            log.info("房间不存在，roomId:{}", roomId);
            baseServerEvent.sendRoomDoesNotExist(ch, roomId);
            return;
        }
        if (room.getPlayerNum().get() == 3) {
            //房间已满
            log.info("房间已满，roomId:{}", roomId);
            baseServerEvent.sendRoomPlaying(ch, roomId);
            return;
        }

        if (room.getRoomStatus() == RoomStatus.LANDLORD_ELECT || room.getRoomStatus() == RoomStatus.PLAYING) {
            log.info("房间正在游戏，roomId:{}", roomId);
            baseServerEvent.sendRoomPlaying(ch, roomId);
            return;
        }


        if (serverEventMap.containsKey(ServerEventCode.valueOf(message.getCode()))) {
            serverEventMap.get(ServerEventCode.valueOf(message.getCode())).consumer(ch, message);
        } else {
            log.info("未找到对应的事件:{}", message.getCode());

        }

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Map<String, ServerEvent> eventMap = applicationContext.getBeansOfType(ServerEvent.class);
        eventMap.forEach((k, v) -> {
            log.info("注册事件:{}", v.getEventCode().name());
            serverEventMap.put(v.getEventCode(), v);
        });
    }
}
